package demo.vo.tsdb;

import com.alibaba.fastjson.JSON;
import io.prometheus.client.Collector;
import io.prometheus.client.Counter;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Sample<T> {
    // 指标
    private String metric;
    // 描述
    private String desc;
    // 标签
    private Map<String, String> tags;
    // 创建时间戳
    private Long created;
    // 数据值
    private T stat;


    public Sample(String metric, String desc, Map<String, String> tags, Long created, T stat) {
        this.metric = metric;
        this.desc = desc;
        this.tags = tags;
        this.created = created;
        this.stat = stat;
    }

    public Sample() {
    }

    public static List<Sample<Double>> from(Counter counter) {
        if (counter == null) {
            return Collections.emptyList();
        }
        List<Collector.MetricFamilySamples> metricFamilySamplesList = counter.collect();
        return metricFamilySamplesList.stream()
                .map(Sample::from)
                .flatMap(List::stream)
                .collect(Collectors.toList());
    }

    public static List<Sample<Double>> from(Collector.MetricFamilySamples metricFamilySamples) {
        if (metricFamilySamples == null || metricFamilySamples.samples == null) {
            return Collections.emptyList();
        }
        String name = metricFamilySamples.name;// 指标名称
        Collector.Type type = metricFamilySamples.type;// 指标类型
        String help = metricFamilySamples.help;// 帮助信息
        return metricFamilySamples.samples// 样本列表
                .stream()
                .filter(sample -> !sample.name.endsWith("_created"))
                .map(s -> {
                    Sample<Double> tmp = new Sample<>();
                    tmp.setMetric(name);
                    tmp.setDesc(help);
                    Map<String, String> tags;
                    if (s.labelNames == null || s.labelNames.isEmpty()) {
                        tags = Collections.emptyMap();
                    } else {
                        tags = new HashMap<>(s.labelNames.size());
                        for (int i = 0; i < s.labelNames.size(); i++) {
                            tags.put(s.labelNames.get(i), s.labelValues.get(i));
                        }
                    }
                    tmp.setTags(tags);
                    tmp.setCreated(s.timestampMs);
                    tmp.setValue(s.value);
                    return tmp;
                }).collect(Collectors.toList());
    }

    public String getMetric() {
        return metric;
    }

    public void setMetric(String metric) {
        this.metric = metric;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public Map<String, String> getTags() {
        return tags;
    }

    public void setTags(Map<String, String> tags) {
        this.tags = tags;
    }

    public Long getCreated() {
        return created;
    }

    public void setCreated(Long created) {
        this.created = created;
    }

    public T getValue() {
        return stat;
    }

    public void setValue(T value) {
        this.stat = value;
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}
